// dotnet "C:\Program Files\dotnet\sdk\6.0.400\Roslyn\bincore\csc.dll" -nologo -t:library -r:"C:\Program Files\dotnet\shared\Microsoft.NETCore.App\5.0.17\System.dll" -r:"C:\Program Files\dotnet\shared\Microsoft.NETCore.App\5.0.17\System.Collections.dll" -r:"..\..\..\The Scroll of Taiwu_Data\Managed\0Harmony.dll" -r:"C:\Program Files\dotnet\shared\Microsoft.NETCore.App\5.0.17\mscorlib.dll" -r:"..\..\..\Backend\GameData.dll" -r:"..\..\..\Backend\Redzen.dll" -r:"..\..\..\The Scroll of Taiwu_Data\Managed\TaiwuModdingLib.dll" -r:"C:\Program Files\dotnet\shared\Microsoft.NETCore.App\5.0.17\System.Private.CoreLib.dll" -r:"C:\Program Files\dotnet\shared\Microsoft.NETCore.App\5.0.17\System.Runtime.dll" -unsafe -optimize -deterministic Backend.cs -out:Backend.dll
// -r:"..\..\..\The Scroll of Taiwu_Data\Managed\Mono.Cecil.dll" -r:"..\..\..\The Scroll of Taiwu_Data\Managed\System.Core.dll"   -r:"..\..\..\The Scroll of Taiwu_Data\Managed\System.Composition.AttributedModel.dll" -r:"C:\Program Files\dotnet\shared\Microsoft.NETCore.App\5.0.17\System.Runtime.dll" 
/**
 *  Everyone's Unity Game Plugin
 *  Copyright (C) 2022 Neutron3529
 *
 *  This program is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU Affero General Public License as
 *  published by the Free Software Foundation, either version 3 of the
 *  License, or (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU Affero General Public License for more details.
 *
 *  You should have received a copy of the GNU Affero General Public License
 *  along with this program.  If not, see <https://www.gnu.org/licenses/>.
 */
 
 // Backend: ProcessMethodCall -> CallMethod -> ...
using System;
using System.Reflection;
using System.Reflection.Emit;
using System.Collections.Generic;
using HarmonyLib;

namespace AllYellowPerk_Backend;
[TaiwuModdingLib.Core.Plugin.PluginConfig("AllYellowPerk_Backend","NobodyCares","0.1.1")]
public class AllYellowPerk_Backend : TaiwuModdingLib.Core.Plugin.TaiwuRemakeHarmonyPlugin {
	public override void Initialize() {
		this.HarmonyInstance.PatchAll(typeof(AllYellowPerk));
	}
	public class AllYellowPerk {
		[HarmonyTranspiler]
		[HarmonyPatch(typeof(GameData.Domains.Taiwu.TaiwuDomain),"InitSkillBreakPlate")]
		public static IEnumerable<CodeInstruction> Transpiler(MethodBase __originalMethod, IEnumerable<CodeInstruction> instructions) {
			instructions = new CodeMatcher(instructions)
				.MatchForward(false, // false = move at the start of the match, true = move at the end of the match
					new CodeMatch(i=>i.opcode==OpCodes.Ldfld && ( (FieldInfo)i.operand==typeof(Config.SkillBreakPlateItem).GetField("PlateWidth") || (FieldInfo)i.operand==typeof(Config.SkillBreakPlateItem).GetField("PlateHeight") ))
				).Repeat( matcher => // Do the following for each match
					matcher.Advance(1).InsertAndAdvance(
						new CodeInstruction(OpCodes.Ldc_I4_2),
						new CodeInstruction(OpCodes.Add)
					)
				).InstructionEnumeration();
			return instructions;
		}
		[HarmonyPrefix]
		[HarmonyPatch(typeof(GameData.Domains.CombatSkill.CombatSkillDomain),"GetBonusBreakGrids")]
		public static bool Prefix(ref List<Config.BreakGrid> __result,short skillTemplateId, sbyte behaviorType){
			Config.SkillBreakGridListItem configData = Config.SkillBreakGridList.Instance[skillTemplateId];
			switch (behaviorType)
			{
			case 0:
				__result = configData.BreakGridListJust;
				break;
			case 1:
				__result = configData.BreakGridListKind;
				break;
			case 2:
				__result = configData.BreakGridListEven;
				break;
			case 3:
				__result = configData.BreakGridListRebel;
				break;
			case 4:
				__result = configData.BreakGridListEgoistic;
				break;
			default:
				__result = null;
				return false;
			}
			__result = new List<Config.BreakGrid>(__result);
			foreach(List<Config.BreakGrid> list in new List<Config.BreakGrid>[]{configData.BreakGridListJust,configData.BreakGridListKind,configData.BreakGridListEven,configData.BreakGridListRebel,configData.BreakGridListEgoistic}){
				foreach(Config.BreakGrid item in list){
					bool flag=true;
					for(int i=0;i<__result.Count;i++){
						if(__result[i].BonusType==item.BonusType){
							if(__result[i].GridCount<item.BonusType){
								__result[i]=item;
							}
							flag=false;
							break;
						}
					}
					if(flag){
						__result.Add(item);
					}
				}
			}
			return false;
		}
	}
}